home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Utilities / FindOpenDocFolder.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  7.5 KB  |  312 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     File:        FindOpenDocFolder.c
  4.     
  5.     Contents:    Utility routines for finding OpenDoc folders by looking
  6.                 in several places.
  7.     
  8.     Owned by:    Troy Gaul
  9.     
  10.     Copyright:    © 1996 Apple Computer, Inc.  All rights reserved.
  11.     
  12.     Change History (most recent first):
  13.     
  14.          <1>      12/19/96    TJ        first checked in
  15.         12/18/96    TAG        Created.
  16.     
  17. */
  18.  
  19. #ifndef _FINDOPENDOCFOLDER_
  20. #include "FindOpenDocFolder.h"
  21. #endif
  22.  
  23. #ifndef __RESOURCES__
  24. #include <Resources.h>
  25. #endif
  26.  
  27. #ifndef __ERRORS__
  28. #include <Errors.h>
  29. #endif
  30.  
  31. #ifndef __SCRIPT__
  32. #include <Script.h>
  33. #endif
  34.  
  35. //------------------------------------------------------------------------------
  36. //    Constants
  37. //------------------------------------------------------------------------------
  38. enum
  39. {
  40.     kOpenDocFoldersFLDxResourceID = 128
  41. };
  42.  
  43. //------------------------------------------------------------------------------
  44. //    DirIDFromSpecialPath (from AtomUtils)
  45. //------------------------------------------------------------------------------
  46. static long
  47. DirIDFromSpecialPath(StringPtr path, short vRefNum)
  48. {
  49.     StringPtr    s;
  50.     OSType        folderType;
  51.     short        foundVrefNum;
  52.     long        foundDirID;
  53.     OSErr        err;
  54.     
  55.     for (s = path ; s[0] != '-' ; s++)                //    step over 'spcl'
  56.         ;
  57.     
  58.     BlockMove(&s[1], &folderType, 4);
  59.     err = FindFolder(vRefNum, folderType, kDontCreateFolder, &foundVrefNum, &foundDirID);
  60.     
  61.     return foundDirID;
  62. }
  63.  
  64. //------------------------------------------------------------------------------
  65. //    PathFromSpecialPath (from AtomUtils)
  66. //------------------------------------------------------------------------------
  67. static void
  68. PathFromSpecialPath(StringPtr inSpecialPath, StringPtr outPathStorage)
  69. {
  70.     StringPtr s;
  71.     for ( s = inSpecialPath ; *s != ':' ; s++ )
  72.         ;
  73.     
  74.     outPathStorage[0] = inSpecialPath[0] - (s - inSpecialPath) +1;        //    length of rest of string
  75.     BlockMove(s, &(outPathStorage[1]), outPathStorage[0]);
  76. }
  77.  
  78. //------------------------------------------------------------------------------
  79. //    GetNextFLDxEntry
  80. //------------------------------------------------------------------------------
  81. typedef struct FLDxEntry {
  82.     OSType    folderType;
  83.     short    version;
  84.     Str255    folderName;
  85. } FLDxEntry;
  86.  
  87. static Ptr
  88. GetNextFLDxEntry(Ptr inPointer, FLDxEntry* entry)
  89. {
  90.     char* ptr = inPointer;
  91.     
  92.     entry->folderType = *(OSType*) ptr;        // folder type
  93.     ptr += sizeof(OSType);
  94.     
  95.     entry->version = *(short*) ptr;            // version
  96.     ptr += sizeof(short);
  97.     
  98.     ptr += sizeof(Byte);                    // high byte of length
  99.     
  100.     entry->folderName[0] = *(unsigned char*) ptr;
  101.     ptr += sizeof(unsigned char);
  102.     
  103.     BlockMoveData(ptr, entry->folderName + 1, entry->folderName[0]);
  104.     ptr += entry->folderName[0];
  105.     
  106.     if ((entry->folderName[0] % 2) == 1)            // word align it.
  107.         ptr += 1;
  108.  
  109.     return ptr;
  110. }
  111.  
  112. //------------------------------------------------------------------------------
  113. //    GetPathFromFLDxResource
  114. //------------------------------------------------------------------------------
  115. static OSErr
  116. GetPathFromFLDxResource(short inResID, OSType inFolderType, StringPtr outFolderPath)
  117. {
  118.     OSErr err = noErr;
  119.     Boolean found = false;
  120.     Handle folderRes;
  121.     long size;
  122.     Ptr ptr, end;
  123.     FLDxEntry entry;
  124.     
  125.     folderRes = Get1Resource('fld#', inResID);
  126.     if (folderRes == NULL)
  127.     {
  128.         err = ResError();
  129.         if (err) return err;
  130.         return resNotFound;
  131.     }
  132.     
  133.     size = GetHandleSize(folderRes);
  134.     ptr = *folderRes;
  135.     end = ptr + size;
  136.     
  137.     while (ptr < end)
  138.     {
  139.         ptr = GetNextFLDxEntry(ptr, &entry);
  140.         
  141.         if (entry.folderType == inFolderType)
  142.         {
  143.             found = true;
  144.             break;
  145.         }
  146.     }
  147.     
  148.     if (found)
  149.         BlockMoveData(entry.folderName, outFolderPath, entry.folderName[0] + 1);
  150.     else
  151.         err = fnfErr;
  152.     
  153.     ReleaseResource(folderRes);        // !!!!! this is fine as long as noone else is using it.
  154.     
  155.     return err;
  156. }
  157.  
  158. //------------------------------------------------------------------------------
  159. //    GetFolderFromOpenDocFoldersFLDx
  160. //------------------------------------------------------------------------------
  161. static OSErr
  162. GetFolderFromOpenDocFoldersFLDx(short inVRefNum, OSType inFolderType,
  163.                                 StringPtr outFolderPath)
  164. {
  165.     OSErr err = noErr;
  166.     short sysVRefNum;
  167.     long  sysDirID;
  168.     FSSpec foldersFileSpec;
  169.     short saveResFile = CurResFile();
  170.     short resFileID;
  171.     
  172.     // Find the System Folder.
  173.     err = FindFolder(inVRefNum, kSystemFolderType, kDontCreateFolder,  &sysVRefNum, &sysDirID);
  174.     if (err) return err;
  175.     
  176.     // Find the invisible OpenDocFolder• file.
  177.     err = FSMakeFSSpec(sysVRefNum, sysDirID, "\pOpenDocFolders•", &foldersFileSpec);
  178.     if (err) return err;
  179.     
  180.     // Open the resource file.
  181.     resFileID = FSpOpenResFile(&foldersFileSpec, fsRdPerm);
  182.     err = noErr;
  183.     if (resFileID == -1)
  184.         err = ResError();
  185.     
  186.     // Get the pathname from the resource.
  187.     if (err == noErr)
  188.     {
  189.         UseResFile(resFileID);    // !!!!! not sure this is needed
  190.         err = GetPathFromFLDxResource(kOpenDocFoldersFLDxResourceID, 
  191.                                       inFolderType, outFolderPath);
  192.         CloseResFile(resFileID);
  193.     }
  194.     
  195.     UseResFile(saveResFile);
  196.     
  197.     return err;
  198. }
  199.  
  200. //——————————————————————————————————————————————————————————————————————————————
  201. //    GetDirectoryDirID
  202. //——————————————————————————————————————————————————————————————————————————————
  203. static OSErr
  204. GetDirectoryDirID(const FSSpec* inDirectory, long *outDirID) 
  205. {
  206.     CInfoPBRec pb;                    // parameter block used to access files
  207.     OSErr err = noErr;
  208.     
  209.     *outDirID = 0;
  210.  
  211.     // Get the directory ID of this directory (rather than its parent)
  212.     pb.dirInfo.ioVRefNum    = inDirectory->vRefNum;
  213.     pb.dirInfo.ioDrDirID    = inDirectory->parID;
  214.     pb.dirInfo.ioNamePtr    = (StringPtr) inDirectory->name;
  215.     pb.dirInfo.ioFDirIndex    = 0;        // get directory id of _this_ directory
  216.     
  217.     err = PBGetCatInfoSync(&pb);
  218.     if (err) return err;
  219.     
  220.     *outDirID = pb.dirInfo.ioDrDirID;
  221.     return err;
  222. }
  223.  
  224. //------------------------------------------------------------------------------
  225. //    FindOpenDocFolder
  226. //------------------------------------------------------------------------------
  227. pascal OSErr
  228. FindOpenDocFolder(short inVRefNum, OSType inFolderType, Boolean inCreateFolder,
  229.                   short* outFoundVRefNum, long* outFoundDirID)
  230. {
  231.     OSErr err = noErr;
  232.     Str255 specialPath;
  233.     Str255 path;
  234.     FSSpec foundFolderSpec;
  235.     long specialDirID;
  236.     
  237.     // First, try FindFolder to see if it's now supported.
  238.     err = FindFolder(inVRefNum, inFolderType, inCreateFolder, outFoundVRefNum,
  239.                      outFoundDirID);
  240.     if (err != fnfErr)
  241.         return err;
  242.     
  243.     // FindFolder didn't work, so look for the invisible file.
  244.     *outFoundVRefNum = inVRefNum;
  245.     
  246.     err = GetFolderFromOpenDocFoldersFLDx(inVRefNum, inFolderType, specialPath);
  247.     
  248.     // Problem finding/reading invisible file, look in the resoruce chain:
  249.     if (err)
  250.         err = GetPathFromFLDxResource(kOpenDocFLDxResourceID, inFolderType, specialPath);
  251.     if (err) return err;
  252.     
  253.     if ( specialPath[1] != ':' )                    //    Found SpecialFolder
  254.     {
  255.         specialDirID = DirIDFromSpecialPath(specialPath, inVRefNum);
  256.         
  257.         // Using the relative path, find the folder.
  258.         PathFromSpecialPath(specialPath, path);
  259.     }
  260.     else
  261.     {
  262.         // This was a target pathname like ':Folder 1:FileName', no chopping necessary
  263.  
  264.         BlockMove(&specialPath, path, specialPath[0] + 1);
  265.  
  266.         // The target was off of the root, not the blessed, so adjust the dirID we'll look for the file
  267.         // to the root of the target volume.
  268.  
  269.         specialDirID = 0;
  270.     }
  271.     
  272.     // Get the directory specified at the front of the special path.
  273.     err = FSMakeFSSpec(*outFoundVRefNum, specialDirID, path, &foundFolderSpec);
  274.     
  275.     // It might not be there. 
  276.     if (err == fnfErr)
  277.     {
  278.         // If not, we might need to create it.
  279.         if (inCreateFolder)
  280.             err = FSpDirCreate(&foundFolderSpec, smSystemScript, outFoundDirID);
  281.     }
  282.     else if (err == noErr)
  283.     {
  284.         // If so, get it's directory ID to return.
  285.         GetDirectoryDirID(&foundFolderSpec, outFoundDirID);
  286.     }
  287.     
  288.     return err;
  289. }
  290.  
  291. //------------------------------------------------------------------------------
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.